package main

import (
	"awesomeProject/goods-web/global"
	"awesomeProject/goods-web/initialize"
	"awesomeProject/goods-web/utils"
	"awesomeProject/goods-web/utils/register/consul"
	"fmt"
	"github.com/google/uuid"
	"github.com/spf13/viper"
	"os"
	"os/signal"
	"syscall"

	"go.uber.org/zap"
)

func main() {
	// 初始化logger
	initialize.InitLogger()

	// 初始化配置文件
	initialize.InitConfig()

	// 初始化服务器的链接
	initialize.InitSrvConn()

	// 本地开发环境下，我们端口号根据.yaml配置文件，如果是线上开发环境，就选择系统已有的
	viper.AutomaticEnv()
	debug := viper.GetBool("SALE_SYSTEM") // 注意这个系统环境变量我还没有配置，所以下面多半就是随机Port

	if !debug { // 线上开发环境使用系统的，如果想要随机的就设置为 if debug
		port, err := utils.GetFreePort() // 获取系统中可用的端口号
		if err == nil {                  // 表示没有错误，有错误就恢复默认
			global.ServerConfig.Port = port
		}
	}

	// 初始化routers并启动
	router := initialize.Router()

	// 初始化Sentinel
	initialize.InitSentinel()

	// 可选择服务注册模块
	serviceId := uuid.New().String()
	// 选择consul作为注册中心 -- 如何指定，选择utils/register/ 下的consul包 还是 etcd包
	consulClient := consul.NewRegistryClient(global.ServerConfig.ConsulInfo.Host, global.ServerConfig.ConsulInfo.Port)
	err := consulClient.Register(global.ServerConfig.Host, global.ServerConfig.Port, global.ServerConfig.Name, global.ServerConfig.Tags, serviceId)
	if err != nil {
		zap.S().Panic("服务注册失败", err.Error())
	}
	// 后续如果想要缓存其他的注册中心解决方案，就可以在utils中实现
	//etcdClient := etcd.NewRegistryClient(global.ServerConfig.ConsulInfo.Host, global.ServerConfig.ConsulInfo.Port)

	zap.S().Infof("服务器成功启动，端口为: %d", global.ServerConfig.Port)

	// 开启协程来运行
	go func() {
		err = router.Run(fmt.Sprintf(":%d", global.ServerConfig.Port))
		if err != nil {
			zap.S().Error("启动失败，失败原因: " + err.Error())
		}
	}()

	quit := make(chan os.Signal)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) // 关心退出信息
	<-quit
	if err = consulClient.Deregister(serviceId); err != nil { // 这里会出现serviceId对应的服务在consul中提前退出，但是
		zap.S().Panic("注销失败")
	} else {
		zap.S().Info("注销成功")
	}

}
